/**
 * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.opsli.modulars.contract.contractinfo.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.opsli.core.base.service.impl.CrudServiceImpl;

import org.opsli.modulars.contract.contractinfo.entity.Contract;
import org.opsli.api.wrapper.contract.contractinfo.ContractModel;
import org.opsli.modulars.contract.contractinfo.service.IContractService;
import org.opsli.modulars.contract.contractinfo.mapper.ContractMapper;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * 会员合同 Service Impl
 *
 * @author 17607080935
 * @date 2025-07-07 16:42:17
 */
@Slf4j
@Service
public class ContractServiceImpl extends CrudServiceImpl<ContractMapper, Contract, ContractModel>
        implements IContractService {

    @Autowired(required = false)
    private ContractMapper mapper;

    @Autowired
    private ApplicationEventPublisher eventPublisher;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ContractModel insert(ContractModel model) {
        // 执行基础插入
        ContractModel result = super.insert(model);

        // 如果合同需要审批，发布审批事件
        if (needsApproval(model)) {
            try {
                publishApprovalEvent(result, "CONTRACT_CREATED");
                log.info("已发布合同审批事件: contractId={}", result.getId());
            } catch (Exception e) {
                log.warn("发布合同审批事件失败: contractId={}, error={}", result.getId(), e.getMessage());
            }
        }

        return result;
    }

    @Override
    public boolean submitForApproval(String contractId) {
        try {
            ContractModel contract = super.get(contractId);
            if (contract == null) {
                log.error("合同不存在: contractId={}", contractId);
                return false;
            }

            // 发布审批提交事件
            publishApprovalEvent(contract, "CONTRACT_SUBMIT_APPROVAL");

            // 更新合同状态为待审批
            contract.setStatus("PENDING_APPROVAL");
            super.update(contract);

            log.info("合同审批提交成功: contractId={}", contractId);
            return true;

        } catch (Exception e) {
            log.error("提交合同审批失败: contractId={}", contractId, e);
            return false;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void onApprovalApproved(String contractId) {
        try {
            ContractModel contract = super.get(contractId);
            if (contract == null) {
                log.warn("处理审批通过时，合同不存在: contractId={}", contractId);
                return;
            }

            // 更新合同状态为生效
            contract.setStatus("ACTIVE");
            super.update(contract);

            log.info("合同审批通过，状态已更新: contractId={}", contractId);

        } catch (Exception e) {
            log.error("处理合同审批通过失败: contractId={}", contractId, e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void onApprovalRejected(String contractId) {
        try {
            ContractModel contract = super.get(contractId);
            if (contract == null) {
                log.warn("处理审批拒绝时，合同不存在: contractId={}", contractId);
                return;
            }

            // 更新合同状态为拒绝
            contract.setStatus("REJECTED");
            super.update(contract);

            log.info("合同审批拒绝，状态已更新: contractId={}", contractId);

        } catch (Exception e) {
            log.error("处理合同审批拒绝失败: contractId={}", contractId, e);
        }
    }

    @Override
    public String getApprovalStatus(String contractId) {
        try {
            // 这里可以通过HTTP调用或其他方式查询审批状态
            // 暂时返回null，表示没有集成
            return null;
        } catch (Exception e) {
            log.error("获取合同审批状态失败: contractId={}", contractId, e);
            return null;
        }
    }

    /**
     * 发布审批事件
     */
    private void publishApprovalEvent(ContractModel contract, String eventType) {
        try {
            Map<String, Object> eventData = new HashMap<>();
            eventData.put("eventType", eventType);
            eventData.put("businessId", contract.getId());
            eventData.put("businessType", "CONTRACT");
            eventData.put("contractId", contract.getContractId());
            eventData.put("customerId", contract.getCustomerId());
            eventData.put("courseId", contract.getCourseId());
            eventData.put("totalAmount", contract.getTotalAmount());
            eventData.put("discountAmount", contract.getDiscountAmount());
            eventData.put("lessonsNumber", contract.getLessonsNumber());
            eventData.put("paymentMethod", contract.getPaymentMethod());

            // 创建事件对象并发布
            ContractApprovalEvent event = new ContractApprovalEvent(this, eventData);
            eventPublisher.publishEvent(event);

            log.info("已发布合同事件: contractId={}, eventType={}", contract.getId(), eventType);

        } catch (Exception e) {
            log.error("发布合同事件失败: contractId={}, eventType={}", contract.getId(), eventType, e);
        }
    }

    /**
     * 判断合同是否需要审批
     */
    private boolean needsApproval(ContractModel contract) {
        // 审批规则：
        // 1. 合同金额超过10000元需要审批
        // 2. 优惠金额超过1000元需要审批
        // 3. 课时数超过100需要审批

        if (contract.getTotalAmount() != null && contract.getTotalAmount().compareTo(new BigDecimal("10000")) > 0) {
            return true;
        }

        if (contract.getDiscountAmount() != null
                && contract.getDiscountAmount().compareTo(new BigDecimal("1000")) > 0) {
            return true;
        }

        if (contract.getLessonsNumber() != null && contract.getLessonsNumber() > 100) {
            return true;
        }

        return false;
    }

    /**
     * 合同审批事件
     */
    public static class ContractApprovalEvent {
        private final Object source;
        private final Map<String, Object> eventData;

        public ContractApprovalEvent(Object source, Map<String, Object> eventData) {
            this.source = source;
            this.eventData = eventData;
        }

        public Object getSource() {
            return source;
        }

        public Map<String, Object> getEventData() {
            return eventData;
        }
    }

}